package com.kongzue.stacklabelview;

import com.kongzue.stacklabelview.utils.AttrUtils;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.render.Canvas;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.util.ArrayList;
import java.util.List;

/**
 * Author: @Kongzue
 * Github: https://github.com/kongzue/
 * Homepage: http://kongzue.com/
 * Mail: myzcxhh@live.cn
 *
 * @since 2019/4/15 01:13
 */
public class StackLayout extends ComponentContainer implements Component.DrawTask, Component.EstimateSizeListener, ComponentContainer.ArrangeListener {
    private static HiLogLabel hiLogLabel = new HiLogLabel(HiLog.LOG_APP, 0x222, "my_app");
    private Context context;
    private int itemMargin = 0;
    private int widthSize;

    /**
     * 初始化
     *
     * @param context context
     */
    public StackLayout(Context context) {
        super(context);
        this.context = context;
    }

    /**
     * 初始化
     *
     * @param context context
     * @param attrs attrs
     */
    public StackLayout(Context context, AttrSet attrs) {
        super(context, attrs);
        this.context = context;
        loadAttrs(context, attrs);
    }

    /**
     * 初始化
     *
     * @param context context
     * @param attrs attrs
     * @param defStyleAttr defStyleAttr
     */
    public StackLayout(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs);
        this.context = context;
        loadAttrs(context, attrs);
    }

    @Override
    public boolean onArrange(int left, int top, int width, int height) {
        return false;
    }

    private void loadAttrs(Context context, AttrSet attrs) {
        try {
            // 默认值
            itemMargin = dp2px(4);

            // 加载值
            itemMargin = AttrUtils.getDimensionValueByAttr(attrs, "itemMargin", itemMargin);
        } catch (Exception e) {
            HiLog.info(hiLogLabel, "error-->" + e.getMessage());
        }

        setEstimateSizeListener(this);
        setArrangeListener(this);
    }

    private List<Component> items;
    private int newHeight = 0;

    @Override
    public boolean onEstimateSize(int width, int i1) {

        widthSize = EstimateSpec.getSize(width);
        setEstimatedSize(widthSize, newHeight); // 设置宽高
        refreshViews();
        return false;
    }

    private void refreshViews() {
        int maxWidth = getEstimatedWidth();

        items = new ArrayList<>();
        for (int i = 0; i < getChildCount(); i++) {
            Component child = getComponentAt(i);
            if (child.getVisibility() == VISIBLE) {
                items.add(getComponentAt(i));
            }
        }

        newHeight = 0;
        if (items != null && !items.isEmpty()) {
            int l1 = 0, t1 = 0, r1 = 0, b1 = 0;
            for (int i = 0; i < items.size(); i++) {
                Component item = items.get(i);

                int mWidth = Component.EstimateSpec.getSizeWithMode(0, EstimateSpec.UNCONSTRAINT); // AT_MOST：先按照最大宽度计算，如果小于则按实际值，如果大于，按最大宽度
                int mHeight = Component.EstimateSpec.getSizeWithMode(0, EstimateSpec.UNCONSTRAINT); // UNSPECIFIED：不确定，根据实际情况计算
                item.estimateSize(mWidth, mHeight);

                int childWidth = item.getEstimatedWidth();
                int childHeight = item.getEstimatedHeight();

                if ((l1 + childWidth) > maxWidth) {
                    l1 = 0;
                    t1 = t1 + childHeight + itemMargin;
                }

                r1 = l1 + childWidth;

                if (childWidth > maxWidth) {
                    r1 = maxWidth;
                }

                b1 = t1 + childHeight;

                item.arrange(l1, t1, r1, b1);

                l1 = l1 + childWidth + itemMargin;

                newHeight = t1 + childHeight;
            }
        }
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {

    }

    private int dp2px(float dpValue) {
        return (int) (0.5f + dpValue * DisplayManager.getInstance().getDefaultDisplay(context).get().getAttributes().densityPixels);
    }
}
